package cn.tedu.test.charging.rabbitmq;

import com.rabbitmq.client.*;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * 声明组件的测试类
 * 链接rabbitmq实现一些功能,必定需要用到交换机 与队列
 * 使用之前提前 准备好交换机和队列的组件 所以需要声明(创建)
 */
public class Declare {
    //需要先准备一个底层连接对象 可以是长连接,也可以直接获取短链接
    private Connection connection;
    //利用测试框架@Before将connection初始化
    //框架 在构建某个对象 过程非常复杂,会使用builder,如果构建过程重复,频繁,固定factory
    @Before
    public void init() throws IOException, TimeoutException {
        //创建一个连接工厂,提供工厂的参数 连接rabbtimq的参数
        ConnectionFactory factory = new ConnectionFactory();
        //rabbitmq-server服务端 ip 与 端口 TCP协议
        factory.setHost("192.168.8.100");
        factory.setPort(5672);
        //提供用户名密码 本地local guest/guest 虚拟机admin/123456
        factory.setUsername("admin");
        factory.setPassword("123456");
        //rabbitmq virtual做数据隔离 连接的虚拟主机不一样,能够使用的交换机 队列 消息 是不同
        factory.setVirtualHost("/");
        connection= factory.newConnection();
    }
    //声明我们所需要的组件
    @Test
    public void declareComponent() throws IOException, TimeoutException {
        //可以声明一个队列 指定队列属性 包括 名称,包括设置 队列最大消息长度 最大消息大小...
        Channel channel = connection.createChannel();
        //执行任务
        /**
         * String queue: 队列名称 在同一个虚拟主机virtual-host中 队列名称 是队列的唯一标识.
         * Boolean durable: 队列是否持久化,如果true,在rabbitmq关机重启后,队列依然存在的.
         * Boolean exclusive: 队列是否独占,如果true,只有当前连接的channel才能使用队列,false 当前测试不可执行了
         * Boolean autoDelete: 队列是否自动删除,如果true,当从第一个消费者连接开始检查,最后一个消费者断开后,队列消失了
         * Map<String,Object> arguments: 队列的其他属性 包括队列长度,超时时间,消息最大存活时间,设置队列延迟交换机...
         */
        channel.queueDeclare("queue3",true,false,true,null);
        /**
         *声明交换机
         */
        //1.1 路由交换机 绑定queue3 绑定的路由key值 北京
        /**
         * String exchange: 交换机名称
         * String type: 交换机类型 direct fanout topic headers
         * Boolean durable: 交换机是否持久化 如果true 关闭rabbitmq 重启 交换机依然存在
         * Boolean autoDelete: 交换机是否自动删除 如果true 有至少一个交换机或者队列绑定这个交换机之后,直到所有的绑定都解除,自动删除
         * Map<String,Object> arguments: 其他属性,比如是否是直接还是间接交换机
         */
        channel.exchangeDeclare("direct_ex","direct",true,false,null);
        /**
         * 1.2 声明一个 新的交换机 fanout_ex fanout类型
         */
        channel.exchangeDeclare("fanout_ex","fanout",true,false,null);
        /**
         * 1.3 声明一个 主题交换机 topic_ex topic类型
         */
        channel.exchangeDeclare("topic_ex","topic",true,false,null);
        /**
         * 定义队列和交换机的绑定关系
         */
        /**
         * 路由交换机绑定 使用的路由key值 在队列是明确的 "北京"
         */
        channel.queueBind("queue3","direct_ex","北京");
        channel.queueBind("queue3","fanout_ex","上海");
        channel.queueBind("queue3","topic_ex","上海.#");
        //关闭短链接
        channel.close();
    }
    //队列的属性
    @Test
    public void queueDeclareWithArgs() throws IOException {
        Channel channel= connection.createChannel();
        Map<String,Object> argumemts=new HashMap<>();
        //可以在arguments放一些固定的key值 和自定义的value(根据你的需求 给value)
        argumemts.put("x-expires",10000);
        channel.queueDeclare("queue_args",true,false,true,argumemts);
    }

}

